package Form;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.JCheckBox;
import javax.swing.border.LineBorder;

import CACA.CACAClassifier;
import CACA.ClassifierSaver;
import CACA.ModelTestInfo;
import CACA.ORTree;
import CACA.ORTreeNode;
import CACA.RuleInfo;
import DataSetPackage.ArffReader;
import DataSetPackage.Attribute;
import DataSetPackage.CsvReader;
import DataSetPackage.DataSet;
import DataSetPackage.DataSetReader;

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.DefaultComboBoxModel;
import java.awt.SystemColor;
import java.awt.Font;
import javax.swing.JScrollPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTabbedPane;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;

public class MainForm {
	int testMode = 0;
	public CACAClassifier classifier;
	ArrayList<Double> weight;
	private DataSet testData;
	public DataSet dataSet;
	private DataSetReader dataReader;

	DecimalFormat pf = new DecimalFormat("##.###%");

	private JFrame frame;
	JFileChooser fileChooser = new JFileChooser();
	JFileChooser classifierChooser = new JFileChooser();
	JTextArea txtOutput = new JTextArea();
	private JTextField textMinSupp;
	private JTextField textMinConf;
	private JTextField textPercent;
	private JTextField textFieldFold;
	private JTextField textFieldDataSet;
	private JTextField textFieldTestSet;
	private JTextField textFieldSeed;
	JRadioButton rdbtnUseTrainingSet = new JRadioButton("Use training set");
	JRadioButton rdbtnSuppliedTestSet = new JRadioButton("Supplied test set");
	JRadioButton rdbtnPercentageSplit = new JRadioButton("Percentage split");
	JRadioButton rdbtnCrossvalidation = new JRadioButton("Cross-validation");
	JCheckBox chckbxOutputVP = new JCheckBox("Output Vertical Representation");
	JCheckBox chckbxOutputPredictions = new JCheckBox("Output predictions");
	JCheckBox chckbxShowClassificationRule = new JCheckBox(
			"Output classification rules");
	JComboBox<String> comboBoxUnit = new JComboBox<String>();
	JComboBox<String> comboBox = new JComboBox<String>();
	JButton btnTestOnly = new JButton("Test Only");
	JTree tree;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainForm window = new MainForm();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public MainForm() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fileChooser.setFileFilter(new DataFileFilter());
		fileChooser.setMultiSelectionEnabled(false);

		classifierChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		classifierChooser.setFileFilter(new CACAFileFilter());
		classifierChooser.setMultiSelectionEnabled(false);

		frame = new JFrame();
		frame.setMinimumSize(new Dimension(800, 550));
		frame.getContentPane().setBackground(SystemColor.inactiveCaptionBorder);
		BorderLayout borderLayout = (BorderLayout) frame.getContentPane()
				.getLayout();
		borderLayout.setVgap(5);
		borderLayout.setHgap(5);
		frame.setBounds(100, 100, 800, 600);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JPanel panel = new JPanel();
		panel.setBackground(SystemColor.inactiveCaptionBorder);
		frame.getContentPane().add(panel, BorderLayout.WEST);
		panel.setLayout(new BorderLayout(5, 5));

		JPanel panel_1 = new JPanel();
		panel_1.setBackground(SystemColor.inactiveCaptionBorder);
		panel.add(panel_1, BorderLayout.NORTH);
		panel_1.setLayout(new BorderLayout(5, 5));

		JPanel panel_24 = new JPanel();
		panel_24.setBackground(SystemColor.inactiveCaptionBorder);
		panel_1.add(panel_24, BorderLayout.CENTER);
		panel_24.setLayout(new BorderLayout(0, 5));

		JPanel panel_5 = new JPanel();
		panel_24.add(panel_5, BorderLayout.NORTH);
		panel_5.setBackground(SystemColor.text);
		panel_5.setBorder(new LineBorder(SystemColor.inactiveCaption, 2, true));
		panel_5.setLayout(new BorderLayout(5, 5));

		JPanel panel_9 = new JPanel();
		panel_9.setBackground(SystemColor.inactiveCaption);
		panel_9.setBorder(null);
		panel_5.add(panel_9, BorderLayout.NORTH);

		JLabel lblCacaOption = new JLabel("CACA option");
		panel_9.add(lblCacaOption);

		JPanel panel_13 = new JPanel();
		panel_13.setBackground(SystemColor.text);
		panel_5.add(panel_13);
		panel_13.setLayout(new BorderLayout(0, 0));

		JPanel panel_7 = new JPanel();
		panel_7.setBackground(SystemColor.text);
		panel_13.add(panel_7, BorderLayout.NORTH);
		panel_7.setLayout(new GridLayout(0, 1, 0, 0));

		JPanel panel_18 = new JPanel();
		panel_7.add(panel_18);
		panel_18.setBackground(SystemColor.text);
		FlowLayout flowLayout_1 = (FlowLayout) panel_18.getLayout();
		flowLayout_1.setAlignment(FlowLayout.LEFT);

		JLabel lblMinsupp = new JLabel("Minsupp :");
		panel_18.add(lblMinsupp);

		textMinSupp = new JTextField();
		textMinSupp.setText("5");
		panel_18.add(textMinSupp);
		textMinSupp.setColumns(3);

		comboBoxUnit.setBackground(SystemColor.inactiveCaptionBorder);
		comboBoxUnit.setModel(new DefaultComboBoxModel<String>(new String[] {
				"Percent", "NoInstances" }));
		comboBoxUnit.setSelectedIndex(0);
		panel_18.add(comboBoxUnit);

		JPanel panel_19 = new JPanel();
		panel_7.add(panel_19);
		panel_19.setBackground(SystemColor.text);
		FlowLayout flowLayout_5 = (FlowLayout) panel_19.getLayout();
		flowLayout_5.setAlignment(FlowLayout.LEFT);

		JLabel lblMinconf = new JLabel("Minconf :");
		panel_19.add(lblMinconf);

		textMinConf = new JTextField();
		textMinConf.setText("60");
		panel_19.add(textMinConf);
		textMinConf.setColumns(3);

		JLabel label_2 = new JLabel("%");
		panel_19.add(label_2);

		JPanel panel_8 = new JPanel();
		panel_8.setBackground(SystemColor.text);
		panel_13.add(panel_8);
		panel_8.setLayout(new GridLayout(0, 1, 0, 0));

		JButton btnSetWeight = new JButton("Set Weight");
		btnSetWeight.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				String text = "";

				if (weight != null) {
					for (int i = 0; i < weight.size(); i++) {
						text += String.valueOf(weight.get(i)) + " ";
					}
				}
				String input = JOptionPane.showInputDialog(null, "set weight",
						text);
				if (input == null)
					return;
				String[] strs = input.split(" ");
				int k = 0;
				weight = new ArrayList<Double>();
				for (int i = 0; i < strs.length; i++) {
					try {
						double w = Double.parseDouble(strs[i]);
						weight.add(w);
					} catch (Exception e) {
						// TODO: handle exception
					}
				}
			}
		});
		btnSetWeight.setBackground(SystemColor.inactiveCaption);
		panel_8.add(btnSetWeight);

		JPanel panel_21 = new JPanel();
		panel_21.setBackground(SystemColor.text);
		FlowLayout flowLayout_8 = (FlowLayout) panel_21.getLayout();
		flowLayout_8.setAlignment(FlowLayout.LEFT);
		flowLayout_8.setVgap(0);
		panel_8.add(panel_21);

		JLabel lblClass = new JLabel("Class :");
		panel_21.add(lblClass);
		comboBox.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				weight = null;
			}
		});

		comboBox.setBackground(SystemColor.inactiveCaptionBorder);
		comboBox.setModel(new DefaultComboBoxModel<String>(
				new String[] { "<class attribute>" }));
		panel_21.add(comboBox);

		chckbxOutputVP.setBackground(SystemColor.text);
		panel_8.add(chckbxOutputVP);

		chckbxShowClassificationRule.setBackground(SystemColor.text);
		panel_8.add(chckbxShowClassificationRule);

		chckbxOutputPredictions.setBackground(SystemColor.text);
		panel_8.add(chckbxOutputPredictions);

		JPanel panel_6 = new JPanel();
		panel_24.add(panel_6);
		panel_6.setBackground(SystemColor.text);
		panel_6.setBorder(new LineBorder(SystemColor.inactiveCaption, 2, true));
		panel_6.setLayout(new BorderLayout(5, 5));

		JPanel panel_4 = new JPanel();
		panel_4.setBackground(SystemColor.inactiveCaption);
		panel_4.setBorder(null);
		FlowLayout flowLayout_2 = (FlowLayout) panel_4.getLayout();
		flowLayout_2.setHgap(0);
		panel_6.add(panel_4, BorderLayout.NORTH);

		JLabel lblTestOption = new JLabel("Test option");
		panel_4.add(lblTestOption);

		JPanel panel_12 = new JPanel();
		panel_12.setBackground(SystemColor.text);
		panel_6.add(panel_12);
		panel_12.setLayout(new GridLayout(0, 1, 5, 2));

		JPanel panel_22 = new JPanel();
		panel_22.setBackground(SystemColor.window);
		panel_22.setForeground(SystemColor.textText);
		FlowLayout flowLayout_7 = (FlowLayout) panel_22.getLayout();
		flowLayout_7.setVgap(0);
		flowLayout_7.setAlignment(FlowLayout.LEFT);
		panel_12.add(panel_22);

		JLabel lblRandomSeed = new JLabel("Random seed");
		panel_22.add(lblRandomSeed);

		textFieldSeed = new JTextField();
		textFieldSeed.setText("0");
		panel_22.add(textFieldSeed);
		textFieldSeed.setColumns(10);

		JPanel panel_15 = new JPanel();
		FlowLayout flowLayout_12 = (FlowLayout) panel_15.getLayout();
		flowLayout_12.setVgap(0);
		flowLayout_12.setAlignment(FlowLayout.LEFT);
		panel_15.setBackground(SystemColor.text);
		panel_12.add(panel_15);
		panel_15.add(rdbtnUseTrainingSet);
		rdbtnUseTrainingSet.setBackground(SystemColor.text);
		rdbtnUseTrainingSet.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				setTrainingMode(0);
			}
		});

		rdbtnUseTrainingSet.setSelected(true);

		JPanel panel_16 = new JPanel();
		panel_16.setBackground(SystemColor.text);
		FlowLayout flowLayout_6 = (FlowLayout) panel_16.getLayout();
		flowLayout_6.setAlignment(FlowLayout.LEFT);
		flowLayout_6.setVgap(0);
		panel_12.add(panel_16);
		panel_16.add(rdbtnSuppliedTestSet);
		rdbtnSuppliedTestSet.setBackground(SystemColor.text);

		rdbtnSuppliedTestSet.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				setTrainingMode(1);
			}
		});

		JPanel panel_10 = new JPanel();
		panel_10.setBackground(SystemColor.text);
		FlowLayout flowLayout = (FlowLayout) panel_10.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		flowLayout.setVgap(0);
		panel_12.add(panel_10);
		panel_10.add(rdbtnCrossvalidation);
		rdbtnCrossvalidation.setBackground(SystemColor.text);
		rdbtnCrossvalidation.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				setTrainingMode(2);
			}
		});

		JLabel lblFold = new JLabel("Fold");
		panel_10.add(lblFold);

		textFieldFold = new JTextField();
		textFieldFold.setText("10");
		textFieldFold.setEnabled(false);
		panel_10.add(textFieldFold);
		textFieldFold.setColumns(4);

		JPanel panel_17 = new JPanel();
		panel_17.setBackground(SystemColor.text);
		FlowLayout flowLayout_4 = (FlowLayout) panel_17.getLayout();
		flowLayout_4.setAlignment(FlowLayout.LEFT);
		flowLayout_4.setVgap(0);
		panel_12.add(panel_17);
		panel_17.add(rdbtnPercentageSplit);
		rdbtnPercentageSplit.setBackground(SystemColor.text);
		rdbtnPercentageSplit.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				setTrainingMode(3);
			}
		});

		textPercent = new JTextField();
		textPercent.setEnabled(false);
		textPercent.setText("66");
		panel_17.add(textPercent);
		textPercent.setColumns(4);

		JLabel label = new JLabel("%");
		panel_17.add(label);

		JPanel panel_20 = new JPanel();
		panel_20.setBackground(SystemColor.inactiveCaptionBorder);
		panel_1.add(panel_20, BorderLayout.SOUTH);

		JButton btnStart = new JButton("Start");
		btnStart.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				start();
			}
		});
		btnStart.setForeground(SystemColor.inactiveCaptionBorder);
		btnStart.setFont(new Font("Tahoma", Font.BOLD, 14));
		btnStart.setBackground(SystemColor.activeCaption);
		panel_20.add(btnStart);

		JButton btnTestOnly = new JButton("Test Only");
		btnTestOnly.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				if (classifier == null) {
					JOptionPane.showMessageDialog(null, "null classifier!");
					return;
				}
				if (testMode != 1) {
					JOptionPane.showMessageDialog(null,
							"'Supplied test set' test mode only");
					return;
				}
				if (testData == null) {
					JOptionPane.showMessageDialog(null,
							"Please insert test data");
					return;
				}
				txtOutput.setText("");
				PrintResult(classifier.test(testData));
			}
		});
		panel_20.add(btnTestOnly);
		btnTestOnly.setForeground(SystemColor.inactiveCaptionBorder);
		btnTestOnly.setFont(new Font("Tahoma", Font.BOLD, 14));
		btnTestOnly.setBackground(SystemColor.activeCaption);

		JPanel panel_23 = new JPanel();
		panel_1.add(panel_23, BorderLayout.WEST);
		FlowLayout flowLayout_13 = (FlowLayout) panel_23.getLayout();
		flowLayout_13.setHgap(0);
		flowLayout_13.setVgap(0);
		panel_23.setBackground(SystemColor.inactiveCaptionBorder);

		JPanel panel_11 = new JPanel();
		panel_11.setBackground(SystemColor.inactiveCaptionBorder);
		panel.add(panel_11, BorderLayout.CENTER);
		panel_11.setLayout(new GridLayout(0, 1, 0, 0));

		JPanel panel_28 = new JPanel();
		panel.add(panel_28, BorderLayout.WEST);
		FlowLayout flowLayout_9 = (FlowLayout) panel_28.getLayout();
		flowLayout_9.setHgap(0);
		flowLayout_9.setVgap(0);

		JPanel panel_2 = new JPanel();
		panel_2.setBackground(SystemColor.inactiveCaptionBorder);
		frame.getContentPane().add(panel_2, BorderLayout.CENTER);
		panel_2.setLayout(new GridLayout(0, 1, 0, 5));

		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setBackground(SystemColor.inactiveCaptionBorder);
		panel_2.add(tabbedPane);

		JPanel panel_30 = new JPanel();
		tabbedPane.addTab("Out put", null, panel_30, null);
		panel_30.setBackground(SystemColor.inactiveCaption);
		panel_30.setBorder(new LineBorder(new Color(191, 205, 219), 2, true));
		panel_30.setLayout(new BorderLayout(5, 5));

		JLabel lblOutPut = new JLabel("Out put :");
		panel_30.add(lblOutPut, BorderLayout.NORTH);
		lblOutPut.setBackground(SystemColor.inactiveCaption);
		txtOutput.setFont(new Font("Consolas", Font.PLAIN, 12));

		// panel_2.add(txtOutput, BorderLayout.WEST);
		txtOutput.setEditable(false);

		JScrollPane scrollPane = new JScrollPane(txtOutput);
		panel_30.add(scrollPane);

		JPanel panel_29 = new JPanel();
		tabbedPane.addTab("Or-Tree", null, panel_29, null);
		panel_29.setBorder(new LineBorder(SystemColor.inactiveCaption, 2));
		panel_29.setBackground(SystemColor.inactiveCaption);
		panel_29.setLayout(new BorderLayout(0, 5));

		tree = new JTree();
		tree.setForeground(Color.RED);
		// panel_29.add(tree, BorderLayout.CENTER);
		tree.setModel(new DefaultTreeModel(
				new DefaultMutableTreeNode("OR-Tree") {
					private static final long serialVersionUID = 1L;

					{
					}
				}));

		JScrollPane scrollPane_1 = new JScrollPane(tree);
		panel_29.add(scrollPane_1, BorderLayout.CENTER);

		JLabel lblOrtree = new JLabel("OR -Tree");
		panel_29.add(lblOrtree, BorderLayout.NORTH);

		JPanel panel_3 = new JPanel();
		panel_3.setBackground(SystemColor.inactiveCaptionBorder);
		frame.getContentPane().add(panel_3, BorderLayout.EAST);
		panel_3.setLayout(new BorderLayout(0, 0));

		JPanel panel_26 = new JPanel();
		panel_26.setBackground(SystemColor.inactiveCaptionText);
		frame.getContentPane().add(panel_26, BorderLayout.NORTH);
		panel_26.setLayout(new GridLayout(0, 1, 0, 0));

		JPanel panel_32 = new JPanel();
		FlowLayout flowLayout_14 = (FlowLayout) panel_32.getLayout();
		flowLayout_14.setAlignment(FlowLayout.LEFT);
		panel_32.setBackground(SystemColor.inactiveCaptionText);
		panel_26.add(panel_32);

		JButton btnModify = new JButton("Edit Rules List");
		btnModify.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				modifyFormShow();
			}

		});

		JButton btnLoadClasifier = new JButton("Load Clasifier...");
		btnLoadClasifier.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_32.add(btnLoadClasifier);
		btnLoadClasifier.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				load();
			}
		});
		btnLoadClasifier.setBackground(SystemColor.inactiveCaptionBorder);

		JButton btnSaveClasifier = new JButton("Save Clasifier...");
		btnSaveClasifier.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_32.add(btnSaveClasifier);
		btnSaveClasifier.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				save();
			}
		});
		btnSaveClasifier.setBackground(SystemColor.inactiveCaptionBorder);
		btnModify.setForeground(Color.BLACK);
		btnModify.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnModify.setBackground(SystemColor.inactiveCaptionBorder);
		btnModify.setAlignmentX(0.5f);
		panel_32.add(btnModify);
		JButton btnPredictClassAttribute = new JButton("Classify Object");
		btnPredictClassAttribute.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_32.add(btnPredictClassAttribute);

		btnPredictClassAttribute.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		btnPredictClassAttribute.setForeground(SystemColor.textText);
		btnPredictClassAttribute
				.setBackground(SystemColor.inactiveCaptionBorder);
		btnPredictClassAttribute.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				classifyFormShow();
			}

		});
		btnPredictClassAttribute.setAlignmentX(Component.CENTER_ALIGNMENT);

		JPanel panel_14 = new JPanel();
		panel_14.setBackground(SystemColor.inactiveCaptionText);
		panel_26.add(panel_14);
		panel_14.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));

		JLabel lblDataSet = new JLabel("Data Set : ");
		lblDataSet.setForeground(SystemColor.textHighlightText);
		panel_14.add(lblDataSet);

		textFieldDataSet = new JTextField();
		textFieldDataSet.setEditable(false);
		textFieldDataSet.setBackground(SystemColor.inactiveCaptionBorder);
		panel_14.add(textFieldDataSet);
		textFieldDataSet.setColumns(30);

		JButton btnLoadData = new JButton("Browse");
		btnLoadData.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_14.add(btnLoadData);
		btnLoadData.setBackground(SystemColor.inactiveCaptionBorder);
		JButton btnViewData = new JButton("View");
		btnViewData.setFont(new Font("Tahoma", Font.PLAIN, 10));
		panel_14.add(btnViewData);

		btnViewData.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		btnViewData.setBackground(SystemColor.inactiveCaptionBorder);
		btnViewData.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {

				EventQueue.invokeLater(new Runnable() {
					public void run() {
						try {
							if (dataSet != null) {
								ViewDataForm frame = new ViewDataForm(dataSet);
								frame.setVisible(true);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});

			}
		});
		btnLoadData.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent arg0) {
				int nState = fileChooser.showOpenDialog(null);
				if (nState == JFileChooser.APPROVE_OPTION)
				// if (nState != JFileChooser.CANCEL_OPTION)
				{
					File files = fileChooser.getSelectedFile();
					dataSet = loadFromFile(files);

					if (dataSet != null) {
						textFieldDataSet.setText(files.getPath());
						String[] cols = dataSet.getColumnName();

						comboBox.removeAllItems();
						for (int i = 0; i < cols.length; i++) {
							comboBox.addItem(cols[i]);
						}
						comboBox.setSelectedIndex(cols.length - 1);

					} else {
						JOptionPane.showMessageDialog(null, "Bad format");
						textFieldDataSet.setText("");
					}

				}

			}
		});

		JPanel panel_31 = new JPanel();
		panel_31.setBackground(SystemColor.inactiveCaptionText);
		FlowLayout flowLayout_3 = (FlowLayout) panel_31.getLayout();
		flowLayout_3.setVgap(0);
		flowLayout_3.setAlignment(FlowLayout.LEFT);
		panel_26.add(panel_31);

		JLabel lblTestSet = new JLabel("Test Set : ");
		lblTestSet.setForeground(Color.WHITE);
		panel_31.add(lblTestSet);

		textFieldTestSet = new JTextField();
		textFieldTestSet.setEditable(false);
		textFieldTestSet.setBackground(SystemColor.inactiveCaptionBorder);
		textFieldTestSet.setColumns(30);
		panel_31.add(textFieldTestSet);

		JButton btnBrowse = new JButton("Browse");
		btnBrowse.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				int nState = fileChooser.showOpenDialog(null);
				if (nState == JFileChooser.APPROVE_OPTION)
				// if (nState != JFileChooser.CANCEL_OPTION)
				{
					File files = fileChooser.getSelectedFile();
					testData = loadFromFile(files);
					if (dataSet != null) {
						textFieldTestSet.setText(files.getPath());
					} else {
						JOptionPane.showMessageDialog(null, "Bad format");
						textFieldTestSet.setText("");
					}
				}
			}
		});
		btnBrowse.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnBrowse.setBackground(SystemColor.inactiveCaptionBorder);
		panel_31.add(btnBrowse);

		JButton btnView = new JButton("View");
		btnView.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				EventQueue.invokeLater(new Runnable() {
					public void run() {
						try {
							if (testData != null) {
								ViewDataForm frame = new ViewDataForm(testData);
								frame.setVisible(true);
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				});
			}
		});
		btnView.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnView.setBackground(SystemColor.inactiveCaptionBorder);
		panel_31.add(btnView);

		JPanel panel_27 = new JPanel();
		FlowLayout flowLayout_10 = (FlowLayout) panel_27.getLayout();
		flowLayout_10.setVgap(0);
		flowLayout_10.setHgap(0);
		frame.getContentPane().add(panel_27, BorderLayout.SOUTH);
	}

	private DataSet loadFromFile(File files) {

		if (DataFileFilter.getExtension(files).equalsIgnoreCase("arff")) {
			dataReader = new ArffReader();
		} else if (DataFileFilter.getExtension(files).equalsIgnoreCase("csv")) {
			dataReader = new CsvReader();
		}
		try {
			DataSet data = new DataSet();
			data = dataReader.readFile(files.getPath());
			return data;

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	private void setTrainingMode(int mode) {
		testMode = mode;
		if (mode == 0) {
			rdbtnUseTrainingSet.setSelected(true);
		} else {
			rdbtnUseTrainingSet.setSelected(false);
		}
		if (mode == 1) {
			rdbtnSuppliedTestSet.setSelected(true);
		} else {
			rdbtnSuppliedTestSet.setSelected(false);
		}
		if (mode == 2) {
			rdbtnCrossvalidation.setSelected(true);
			textFieldFold.setEnabled(true);
		} else {
			rdbtnCrossvalidation.setSelected(false);
			textFieldFold.setEnabled(false);
		}
		if (mode == 3) {
			rdbtnPercentageSplit.setSelected(true);
			textPercent.setEnabled(true);
		} else {
			rdbtnPercentageSplit.setSelected(false);
			textPercent.setEnabled(false);
		}

	}

	private void start() {
		classifier = new CACAClassifier();

		double[] w = null;
		if (weight != null)
		{		
			int k = dataSet.getAttribute(comboBox.getSelectedIndex())
				.getNumberOfNominal();
			 w = new double[k];
			for (int i = 0; i < k; i++) {
				if (i < weight.size())
					w[i] = weight.get(i);
				else
					w[i] = 1;
			}
		}
		classifier.setClassIndex(comboBox.getSelectedIndex());
		classifier.setWeight(w);
		if (dataSet == null) {
			JOptionPane.showMessageDialog(null, "Please insert data");
			return;
		}

		double minSupp;
		double minConf;
		long seed;
		try {
			minSupp = Double.parseDouble(textMinSupp.getText());
			minConf = Double.parseDouble(textMinConf.getText());
			seed = Long.parseLong(textFieldSeed.getText());
		} catch (Exception ex) {
			JOptionPane
					.showMessageDialog(null,
							"Invalid input ( MinSupp, MinConff or RandomSeed textfield )");
			return;
		}

		ModelTestInfo testInfo;
		if (testMode == 2) {
			testInfo = CrossValidate(minSupp, minConf, seed);

		} else {
			DataSet trainSet;
			DataSet testSet;

			if (testMode == 0) {
				trainSet = dataSet;
				testSet = dataSet;
			} else if (testMode == 1) {
				trainSet = dataSet;

				if (testData == null) {
					JOptionPane.showMessageDialog(null,
							"Please insert test data");
					return;
				}
				testSet = testData;
			} else {
				double percent = 1.0 - Double
						.parseDouble(textPercent.getText()) / 100.0;
				int n = (int) (dataSet.getNumberOfIntances() * percent);
				trainSet = dataSet.duplicateData();
				testSet = trainSet.randomSubData(n, seed);
			}

			testInfo = Test(trainSet, testSet, minSupp, minConf);

		}

		tree.setModel((TreeModel) generateORTree(classifier.getOrTree()));
		PrintResult(testInfo);
	}

	private ModelTestInfo Test(DataSet trainSet, DataSet testSet,
			double minSupp, double minConf) {
		classifier.train(trainSet, minSupp, minConf,
				comboBoxUnit.getSelectedIndex() == 0);
		ModelTestInfo testInfo = classifier.test(testSet);

		txtOutput.setText("");
		PrintOption(testInfo, testSet);
		return testInfo;
	}

	private ModelTestInfo CrossValidate(double minSupp, double minConf,
			long seed) {
		ModelTestInfo testInfo = null;
		DataSet trainSet = dataSet.duplicateData();
		trainSet.randomize(seed);
		int k = Integer.parseInt(textFieldFold.getText());
		double n = (double) trainSet.getNumberOfIntances() / k;
		for (int i = 0; i < k; i++) {
			DataSet subTrainSet = trainSet.duplicateData();
			int offset = (int) (i * n + 0.5);
			int number = (int) ((i + 1) * n + 0.5) - (int) (i * n + 0.5);
			System.out.print(offset);
			System.out.print("-");
			System.out.println(number);

			DataSet subTestSet = subTrainSet.subData(offset, number);
			classifier.train(subTrainSet, minSupp, minConf,
					comboBoxUnit.getSelectedIndex() == 0);
			ModelTestInfo subtestInfo = classifier.test(subTestSet);
			if (testInfo == null) {
				testInfo = subtestInfo;
			} else {
				testInfo.add(subtestInfo);
			}
		}
		txtOutput.setText("");
		PrintOption(testInfo, trainSet);
		return testInfo;
	}

	private void PrintOption(ModelTestInfo testInfo, DataSet testSet) {
		if (chckbxOutputVP.isSelected()) {
			txtOutput.append(classifier.getLogString() + "\n\n");
		}
		if (chckbxShowClassificationRule.isSelected()) {
			txtOutput.append("===== Rules list =====\n");
			String rules[] = getString(classifier.getOrTree());
			for (int i = 0; i < rules.length; i++) {
				txtOutput.append("r" + String.valueOf(i) + ": " + rules[i]
						+ "\n");
			}
			txtOutput.append("\n");
		}
		if (chckbxOutputPredictions.isSelected()) {
			txtOutput.append(tab("No.", 5) + tab("Accurate", 25)
					+ tab("Predict", 25) + "Correct");
			int i = 0;
			for (Iterator<Integer> iterator = testInfo.getPrediction()
					.iterator(); iterator.hasNext(); i++) {
				int label = (int) iterator.next();
				int acc = testSet.getRow(i)[classifier.getClassIndex()];
				txtOutput.append("\n "
						+ tab(String.valueOf(i), 5)
						+ tab(classifier.getClassAttribute().getNominal(acc),
								25)
						+ tab(classifier.getClassAttribute().getNominal(label),
								25) + String.valueOf(label == acc));
			}
			txtOutput.append("\n\n");
		}
	}

	private void PrintResult(ModelTestInfo testInfo) {
		txtOutput.append("===== Result =====\n");

		txtOutput.append("* Nunber of rules :"
				+ String.valueOf(classifier.getOrTree().countRule()));

		txtOutput.append("\n* Correct :"
				+ String.valueOf(testInfo.getCorrect()) + "/"
				+ String.valueOf(testInfo.getTotal()) + " ( Accuracy = "
				+ pf.format(testInfo.getAccuracy()) + " )");

		Attribute classAttribute = classifier.getClassAttribute();
		int k = classAttribute.getNumberOfNominal();

		txtOutput.append("\n* Detailed Accuracy By Class :\n");
		double[] precision = testInfo.getPrecision();
		double[] recall = testInfo.getRecall();

		txtOutput.append(tab("Class", 25));
		txtOutput.append(tab("Precision", 20));
		txtOutput.append(tab("Recall", 20));
		txtOutput
				.append("\n-------------------------------------------------------------");
		for (int i = 0; i < k; i++) {
			txtOutput.append("\n");
			txtOutput.append(tab(classifier.getClassAttribute().getNominal(i),
					25));
			txtOutput.append(tab(pf.format(precision[i]), 20));
			txtOutput.append(tab(pf.format(recall[i]), 20));

		}
		txtOutput
				.append("\n-------------------------------------------------------------\n");
		txtOutput.append(tab("Weighted Avg.", 25));
		txtOutput.append(tab(pf.format(testInfo.getAvgPrecision()), 20));
		txtOutput.append(tab(pf.format(testInfo.getAvgRecall()), 20));

		txtOutput.append("\n\n* Confusion matrix :\n\n");

		for (int i = 0; i < k; i++) {

			txtOutput.append(tab("#" + String.valueOf(i), 6));
		}
		for (int i = 0; i < k; i++) {
			txtOutput.append("\n");
			for (int j = 0; j < k; j++) {
				txtOutput
						.append(tab(
								" "
										+ String.valueOf(testInfo
												.getConfusionMatrix(i, j)), 6));
			}
			txtOutput.append("#" + String.valueOf(i) + " = "
					+ classAttribute.getNominal(i));
		}
	}

	private String tab(String string, int t) {

		if (string.length() > t - 1)
			string = string.substring(0, t - 1);
		int n = t - string.length();
		// String str = string;
		for (int i = 0; i < n; i++) {
			string += " ";
		}
		return string;
	}

	private void classifyFormShow() {

		if (classifier == null) {
			JOptionPane.showMessageDialog(null, "null classifier!");
			return;
		}
		ClassifyForm form = new ClassifyForm(classifier);
		form.setVisible(true);
	}

	public void modifyFormShow() {
		if (classifier == null) {
			JOptionPane.showMessageDialog(null, "null classifier!");
			return;
		}
		ModifyForm form = new ModifyForm(this);
		form.setVisible(true);
	}

	public void save() {
		int nState = classifierChooser.showSaveDialog(null);
		if (nState == JFileChooser.APPROVE_OPTION)
		// if (nState != JFileChooser.CANCEL_OPTION)
		{

			File sfile = classifierChooser.getSelectedFile();
			File file = new File(sfile.getPath() + ".caca");

			ClassifierSaver.save(classifier, file);
		}
	}

	public void load() {
		int nState = classifierChooser.showOpenDialog(null);
		if (nState == JFileChooser.APPROVE_OPTION)
		// if (nState != JFileChooser.CANCEL_OPTION)
		{

			File file = classifierChooser.getSelectedFile();

			classifier = ClassifierSaver.load(file);
			if (classifier != null) {
				tree.setModel((TreeModel) generateORTree(classifier.getOrTree()));
				txtOutput.setText("Loaded : " + file.getPath()
						+ "\nNumber of Rules : "
						+ String.valueOf(classifier.getOrTree().countRule()));
			}
		}
	}

	public TreeModel generateORTree(ORTree orTree) {
		// TODO Auto-generated method stub
		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("OR-Tree");
		writeNode(orTree.getRoot(), rootNode);
		TreeModel tree = new DefaultTreeModel(rootNode);
		return tree;
	}

	public void writeNode(ORTreeNode orNode, DefaultMutableTreeNode node) {
		if (orNode.isLeaf()) {
			RuleInfo ruleInfo = orNode.getRuleInfor();
			double supp = (double) ruleInfo.suppCount
					/ classifier.getNoInstances();
			String nodeName = classifier.label2String(ruleInfo.label)
					+ "       [Supp: " + pf.format(supp) + " Conf: "
					+ pf.format(ruleInfo.conf) + "]";

			node.add(new DefaultMutableTreeNode(nodeName));
		}
		for (Iterator<ORTreeNode> iterator = orNode.getChildNodes().iterator(); iterator
				.hasNext();) {
			ORTreeNode childNode = (ORTreeNode) iterator.next();
			String nodeName = classifier.item2String(childNode.getItem());

			DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
					nodeName);
			writeNode(childNode, newNode);
			node.add(newNode);
		}
	}

	public String[] getString(ORTree orTree) {
		DecimalFormat df = new DecimalFormat("#.##");
		String[] rules = new String[orTree.countRule()];
		int i = 0;
		for (Iterator<ORTreeNode> iterator = orTree.getoRList().iterator(); iterator
				.hasNext(); i++) {
			ORTreeNode node = (ORTreeNode) iterator.next();

			String label = classifier.label2String(node.getRuleInfor().label);
			String rule = "";
			boolean first = true;
			while (node.getItem() != null) {
				if (first) {
					first = false;
				} else {
					rule += "^ ";
				}
				rule += classifier.item2String(node.getItem()) + " ";
				node = node.getFatherNode();
			}
			rule = rule + "=> " + label;

			rules[i] = rule;
		}
		return rules;
	}
}
